

<!DOCTYPE html>
<html lang="zh-CN" data-default-color-scheme=&#34;auto&#34;>



<head>
  <meta charset="UTF-8">
  <link rel="apple-touch-icon" sizes="76x76" href="/img/favicon.png">
  <link rel="icon" type="image/png" href="/img/favicon.png">
  <meta name="viewport"
        content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, shrink-to-fit=no">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  
  <meta name="theme-color" content="#2f4154">
  <meta name="description" content="CodeHope">
  <meta name="author" content="CodeHope">
  <meta name="keywords" content="希望">
  <title>SpringBoot全局异常处理 - CodeHope</title>

  <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" />


  <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/github-markdown-css@4.0.0/github-markdown.min.css" />
  <link  rel="stylesheet" href="/lib/hint/hint.min.css" />

  
    
    
      
      
        
          
          
          
        
        <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs@1.22.0/themes/prism-tomorrow.min.css" />
      
      
        <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs@1.22.0/plugins/line-numbers/prism-line-numbers.min.css" />
      
    
  

  
    <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.css" />
  



<!-- 主题依赖的图标库，不要自行修改 -->

<link rel="stylesheet" href="//at.alicdn.com/t/font_1749284_ba1fz6golrf.css">



<link rel="stylesheet" href="//at.alicdn.com/t/font_1736178_kmeydafke9r.css">


<link  rel="stylesheet" href="/css/main.css" />

<!-- 自定义样式保持在最底部 -->


  <script id="fluid-configs">
    var Fluid = window.Fluid || {};
    var CONFIG = {"hostname":"quancundexiwang.wang","root":"/","version":"1.8.7","typing":{"enable":true,"typeSpeed":70,"cursorChar":"_","loop":false},"anchorjs":{"enable":true,"element":"h1,h2,h3,h4,h5,h6","placement":"left","visible":"hover","icon":""},"progressbar":{"enable":true,"height_px":3,"color":"#29d","options":{"showSpinner":true,"trickleSpeed":100}},"copy_btn":true,"image_zoom":{"enable":true},"toc":{"enable":true,"headingSelector":"h1,h2,h3,h4,h5,h6","collapseDepth":0},"lazyload":{"enable":true,"onlypost":true},"web_analytics":{"enable":false,"baidu":null,"google":null,"gtag":null,"tencent":{"sid":null,"cid":null},"woyaola":null,"cnzz":null,"leancloud":{"app_id":"Mi65hxq7VAFUDwOLeIGAOgiV-gzGzoHsz","app_key":"hMuhiD4FRqhns4giqLiEH9HG","server_url":null}}};
  </script>
  <script  src="/js/utils.js" ></script>
  <script  src="/js/color-schema.js" ></script>
<meta name="generator" content="Hexo 5.3.0"></head>


<body>
  <header style="height: 80vh;">
    <nav id="navbar" class="navbar fixed-top  navbar-expand-lg navbar-dark scrolling-navbar">
  <div class="container">
    <a class="navbar-brand"
       href="/">&nbsp;<strong>CodeHope</strong>&nbsp;</a>

    <button id="navbar-toggler-btn" class="navbar-toggler" type="button" data-toggle="collapse"
            data-target="#navbarSupportedContent"
            aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
      <div class="animated-icon"><span></span><span></span><span></span></div>
    </button>

    <!-- Collapsible content -->
    <div class="collapse navbar-collapse" id="navbarSupportedContent">
      <ul class="navbar-nav ml-auto text-center">
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/">
                <i class="iconfont icon-home-fill"></i>
                村头
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/archives/">
                <i class="iconfont icon-archive-fill"></i>
                归档
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/categories/">
                <i class="iconfont icon-category-fill"></i>
                分类
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/tags/">
                <i class="iconfont icon-tags-fill"></i>
                标签
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/about/">
                <i class="iconfont icon-user-fill"></i>
                我
              </a>
            </li>
          
        
        
          <li class="nav-item" id="search-btn">
            <a class="nav-link" data-toggle="modal" data-target="#modalSearch">&nbsp;<i
                class="iconfont icon-search"></i>&nbsp;</a>
          </li>
        
        
          <li class="nav-item" id="color-toggle-btn">
            <a class="nav-link" href="javascript:">&nbsp;<i
                class="iconfont icon-dark" id="color-toggle-icon"></i>&nbsp;</a>
          </li>
        
      </ul>
    </div>
  </div>
</nav>

    <div class="banner" id="banner" parallax=true
         style="background: url('http://qiniuyun.quancundexiwang.wang/20210502162555.png') repeat center center;
           background-size: cover;">
      <div class="full-bg-img">
        <div class="mask flex-center" style="background-color: rgba(0, 0, 0, 0.3)">
          <div class="page-header text-center fade-in-up">
            <span class="h2" id="subtitle" title="SpringBoot全局异常处理">
              
            </span>

            
              <div class="mt-3">
  
  
    <span class="post-meta">
      <i class="iconfont icon-date-fill" aria-hidden="true"></i>
      <time datetime="2021-05-02 16:27" pubdate>
        2021年5月2日 下午
      </time>
    </span>
  
</div>

<div class="mt-1">
  
    
    <span class="post-meta mr-2">
      <i class="iconfont icon-chart"></i>
      3.3k 字
    </span>
  

  
    
    <span class="post-meta mr-2">
      <i class="iconfont icon-clock-fill"></i>
      
      
      40
       分钟
    </span>
  

  
  
</div>

            
          </div>

          
            <div class="scroll-down-bar">
              <i class="iconfont icon-arrowdown"></i>
            </div>
          
        </div>
      </div>
    </div>
  </header>

  <main>
    
      

<div class="container-fluid nopadding-x">
  <div class="row nomargin-x">
    <div class="d-none d-lg-block col-lg-2"></div>
    <div class="col-lg-8 nopadding-x-md">
      <div class="container nopadding-x-md" id="board-ctn">
        <div class="py-5" id="board">
          <article class="post-content mx-auto">
            <!-- SEO header -->
            <h1 style="display: none">SpringBoot全局异常处理</h1>
            
            <div class="markdown-body">
              <h1 id="SpringBoot全局异常处理"><a href="#SpringBoot全局异常处理" class="headerlink" title="SpringBoot全局异常处理"></a><code>SpringBoot</code>全局异常处理</h1><h2 id="1-为什么要做全局异常处理？"><a href="#1-为什么要做全局异常处理？" class="headerlink" title="1. 为什么要做全局异常处理？"></a>1. 为什么要做全局异常处理？</h2><p>写代码，难免遇到一些异常错误！<code>Java</code>中更是各种各样的异常！比如我们做前后端的web项目，模拟一个异常的抛出！</p>
<div class="code-wrapper"><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token annotation punctuation">@RestController</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">CheckComputerController</span> <span class="token punctuation">&#123;</span>

    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">private</span> <span class="token class-name">OsService</span> osService<span class="token punctuation">;</span>

    <span class="token annotation punctuation">@GetMapping</span><span class="token punctuation">(</span><span class="token string">"/queryListCmd"</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">queryListCmd</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">Exception</span> <span class="token punctuation">&#123;</span>
        <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">Exception</span><span class="token punctuation">(</span><span class="token string">"小拉~格局小拉"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></div>
<p>然后抛给前端的大部分都长这样~</p>
<p><img src="http://qiniuyun.quancundexiwang.wang/image-20210429092205874.png" srcset="/img/loading.gif"></p>
<p>作为一个前端来说！遇到这种错误！我肯定会去找后端，进行一次友好的技术讨论的！</p>
<p>那么怎么样返回一些错误的格式，会比较规范呢？因为我们还是学习web服务器端的开发，现在主流的是前后端交互，依赖<code>JSON</code>交换数据，那么我们当然也希望使用格式规范易懂的<code>JSON</code>来给前端反馈各种各样的信息啦！</p>
<p>比如酱紫的<code>json</code></p>
<div class="code-wrapper"><pre class="line-numbers language-json" data-language="json"><code class="language-json"><span class="token punctuation">&#123;</span>
    <span class="token property">"code"</span><span class="token operator">:</span> <span class="token number">10001</span><span class="token punctuation">,</span>
    <span class="token property">"message"</span><span class="token operator">:</span> <span class="token string">"小了,格局小了！"</span><span class="token punctuation">,</span>
    <span class="token property">"request_url"</span><span class="token operator">:</span> <span class="token string">"GET api/v1/queryOrder"</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre></div>
<p>那么这就是我们为什么要进行全局的错误拦截的原因了！而且也定下了我们的错误反馈的格式！那么下面就看具体的实现吧！</p>
<h2 id="2-ControllerAdvice-注解概要"><a href="#2-ControllerAdvice-注解概要" class="headerlink" title="2. @ControllerAdvice 注解概要"></a>2. <code>@ControllerAdvice</code> 注解概要</h2> <p style='color:#eaf1f8;background:#443da6;padding:10px;font-weight:bolder;border-radius:15px;line-height:30px;'>【@ControllerAdvice】 是spring 3.2提供的新注解,它是一个controller增强器，ControllerAdvice拆分开来就是Controller Advice，关于Advice，前面我们讲解Spring Aop时讲到，其是用于封装一个切面所有属性的，包括切入点和需要织入的切面逻辑。</p>

<p style='color:#035766;background:#feb856;padding:10px;font-weight:bolder;border-radius:15px;line-height:30px;'>【这里ContrllerAdvice也可以这么理解，其抽象级别应该是用于对Controller进行“切面”环绕的，而具体的业务织入方式则是通过结合其他的注解来实现的】</p>

<p><code>ControllerAdvice</code>在类上声明的注解，其用法主要有三点：</p>
<ul>
<li>结合方法型注解<code>@ExceptionHandler</code>，用于捕获<code>Controller</code>中抛出的指定类型的异常，从而达到不同类型的异常区别处理的目的；</li>
<li>结合方法型注解<code>@InitBinder</code>，用于<code>request</code>中自定义参数解析方式进行注册，从而达到自定义指定格式参数的目的；</li>
<li>结合方法型注解<code>@ModelAttribute</code>，表示其标注的方法将会在目标<code>Controller</code>方法执行之前执行。</li>
</ul>
<p style='color:#815abd;background:#fcdc01;padding:10px;font-weight:bolder;border-radius:15px;line-height:30px;'>【从上面可以看出，@ControllerAdvice的用法基本是将其声明在某个bean上，然后在该bean的方法上使用其他的注解来指定不同的织入逻辑。不过这里@ControllerAdvice并不是使用AOP的方式来织入业务逻辑的，而是Spring内置对其各个逻辑的织入方式进行了内置支持。】</p>

<h2 id="3-ControllerAdvice-注解简单使用"><a href="#3-ControllerAdvice-注解简单使用" class="headerlink" title="3. @ControllerAdvice 注解简单使用"></a>3. <code>@ControllerAdvice</code> 注解简单使用</h2><div class="code-wrapper"><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token annotation punctuation">@ControllerAdvice</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">GlobalException</span> <span class="token punctuation">&#123;</span>

    <span class="token annotation punctuation">@ExceptionHandler</span><span class="token punctuation">(</span>value <span class="token operator">=</span> <span class="token class-name">Exception</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">handleException</span><span class="token punctuation">(</span><span class="token class-name">HttpServletRequest</span> request<span class="token punctuation">,</span> <span class="token class-name">HttpServletResponse</span> response<span class="token punctuation">,</span><span class="token class-name">Exception</span> e<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>

    <span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></div>
<p><img src="http://qiniuyun.quancundexiwang.wang/image-20210430133256259.png" srcset="/img/loading.gif" alt="image-20210430133256259"></p>
<p>因为是拦截的<code>Controller</code>控制器的，所以我们可以拿到请求对象和响应对象，而且这个方法是拦截异常的，所以也能拿到由<code>Controller</code>抛出的异常信息</p>
<p>那么有了这些内容，我们就可以自定义一些异常，在这里统一返回给前端了，但是<code>Java</code>是一个强类型语言，它的异常类型是非常多的！下面我们就把异常进行一些分类处理！</p>
<h2 id="4-异常-的选择"><a href="#4-异常-的选择" class="headerlink" title="4. 异常 的选择"></a>4. 异常 的选择</h2><h3 id="4-1-Java中异常-的选择"><a href="#4-1-Java中异常-的选择" class="headerlink" title="4.1 Java中异常 的选择"></a>4.1 <code>Java</code>中异常 的选择</h3><ul>
<li><code>Error</code> 严格来说不叫做异常！它是一个错误，操作系统或<code>JVM</code>级别的错误！一般会直接影响程序的启动，或者中断程序的运行，一般没有办法通过程序内部的代码去处理。</li>
<li><code>Exception</code> 这个才是程序的异常，通常不会影响整个程序的运行，而且可以通过程序内部的代码异常机制来处理的。<ul>
<li><code>CheckedException</code> 源代码编译前的异常，一些类型错误，语法错误！那么这种异常一般我们都在代码里要处理好的</li>
<li><code>RuntimeException</code> 运行时的异常，有可能编译的时候不会出异常！只是编译后运行时，出了异常！</li>
</ul>
</li>
</ul>
<blockquote>
<p>那么对于我们的web开发，一般 <code>CheckedException</code>我们在开发的时候，大部分都是可以在应用没有上线之前，通过强大的IDEA是可以发现的！</p>
</blockquote>
<blockquote>
<p>而且我们主要是做一些前后端交互的时候的一些错误异常的拦截，应该都是在程序运行的时候，反馈的异常，所以会选择<code>RuntimeException</code></p>
</blockquote>
<h3 id="4-2-已知异常和未知异常"><a href="#4-2-已知异常和未知异常" class="headerlink" title="4.2 已知异常和未知异常"></a>4.2 已知异常和未知异常</h3><p style='color:#035766;background:#feb856;padding:10px;font-weight:bolder;border-radius:15px;line-height:30px;'>【什么是已知异常？】</p>

<p>比如这样一个业务场景<del>我们业务要进行一个除法的计算</del>，分母是由前端传递到后端的，那么就要求分母不能为0，如果你考虑到了，那么你就会对这个分母做一个异常的处理，如果前端传进来了0作为分母，那么就抛出一个异常给前端，准确的告诉前端，这个参数不能为0，那么这个就叫做<strong>已知异常</strong>！就是你能在业务中考虑到可能会产生的错误！</p>
<p style='color:#035766;background:#feb856;padding:10px;font-weight:bolder;border-radius:15px;line-height:30px;'>【什么是未知异常？】</p>

<p>那么就相反，可能一些业务可能出错的地方，你没有考虑到！等到出错了之后，这个业务进行不下去，这个情况下，你也要有一些异常的反馈给前端，告诉他出了异常！而且是一个未知异常，这个时候可能就需要根据业务，看看你的业务异常的处理是否完备，最好是能把一些没考虑到的异常从未知异常变为已知异常，增加程序的健壮性！</p>
<h2 id="5-GET-START"><a href="#5-GET-START" class="headerlink" title="5. GET START"></a>5. <code>GET START</code></h2><h3 id="1-定义抛出错误的bean类！"><a href="#1-定义抛出错误的bean类！" class="headerlink" title="1. 定义抛出错误的bean类！"></a>1. 定义抛出错误的bean类！</h3><p>首先根据统一（<code>Unify</code>）的返回格式 <code>UnifyResponse.java</code></p>
<div class="code-wrapper"><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">package</span> <span class="token namespace">com<span class="token punctuation">.</span>codehope<span class="token punctuation">.</span>ch<span class="token punctuation">.</span>core</span><span class="token punctuation">;</span>

<span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>context<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span></span><span class="token class-name">ComponentScan</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>stereotype<span class="token punctuation">.</span></span><span class="token class-name">Component</span><span class="token punctuation">;</span>

<span class="token annotation punctuation">@Component</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">UnifyResponse</span> <span class="token punctuation">&#123;</span>
    <span class="token keyword">private</span> <span class="token class-name">Integer</span> code<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> message<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> url<span class="token punctuation">;</span>

    <span class="token keyword">public</span> <span class="token class-name">UnifyResponse</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>

    <span class="token punctuation">&#125;</span>

    <span class="token keyword">public</span> <span class="token class-name">Integer</span> <span class="token function">getCode</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token keyword">return</span> code<span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>

    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setCode</span><span class="token punctuation">(</span><span class="token class-name">Integer</span> code<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>code <span class="token operator">=</span> code<span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>

    <span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">getMessage</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token keyword">return</span> message<span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>

    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setMessage</span><span class="token punctuation">(</span><span class="token class-name">String</span> message<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>message <span class="token operator">=</span> message<span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>

    <span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">getUrl</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token keyword">return</span> url<span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>

    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setUrl</span><span class="token punctuation">(</span><span class="token class-name">String</span> url<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>url <span class="token operator">=</span> url<span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></div>
<h3 id="2-自定义异常类"><a href="#2-自定义异常类" class="headerlink" title="2. 自定义异常类"></a>2. 自定义异常类</h3><p>定义一个<code>HttpException</code>作为<code>Http</code>请求相关的错误返回！</p>
<div class="code-wrapper"><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">package</span> <span class="token namespace">com<span class="token punctuation">.</span>codehope<span class="token punctuation">.</span>ch<span class="token punctuation">.</span>exception</span><span class="token punctuation">;</span>

<span class="token comment">//因为拦截的都是exception肯定要继承这个东西啦</span>

<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">HttpException</span> <span class="token keyword">extends</span> <span class="token class-name">Exception</span> <span class="token punctuation">&#123;</span>
    
    <span class="token comment">//自定义的code</span>
    <span class="token keyword">public</span> <span class="token class-name">Integer</span> code<span class="token punctuation">;</span>
    
    <span class="token comment">//http状态码</span>
    <span class="token keyword">public</span> <span class="token class-name">Integer</span> <span class="token class-name">HttpStatus</span><span class="token punctuation">;</span>
    
    <span class="token comment">//请求的Url</span>
    <span class="token keyword">public</span> <span class="token class-name">String</span> url<span class="token punctuation">;</span>
    
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></div>
<p>然后我们定义一个资源未找到的异常类！来试试手！</p>
<p><code>NotFoundException.java</code></p>
<div class="code-wrapper"><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">package</span> <span class="token namespace">com<span class="token punctuation">.</span>codehope<span class="token punctuation">.</span>ch<span class="token punctuation">.</span>exception</span><span class="token punctuation">;</span>

<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">NotFoundException</span> <span class="token keyword">extends</span> <span class="token class-name">HttpException</span> <span class="token punctuation">&#123;</span>
    <span class="token keyword">public</span> <span class="token class-name">NotFoundException</span><span class="token punctuation">(</span><span class="token class-name">Integer</span> code<span class="token punctuation">,</span> <span class="token class-name">String</span> url<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        
        <span class="token comment">//其实这个code也可以写死，这里也可以根据不同的类型去返回自定义的code看需要</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>code <span class="token operator">=</span> code<span class="token punctuation">;</span>
        
        <span class="token class-name"><span class="token namespace">this<span class="token punctuation">.</span></span>HttpStatus</span> <span class="token operator">=</span> <span class="token number">404</span><span class="token punctuation">;</span>
        
        <span class="token comment">//url根据当前控制器的请求的路径，去传入！其实也可</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>url <span class="token operator">=</span> url<span class="token punctuation">;</span>
        
    <span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></div>
<h3 id="3-配置全局异常拦截的类"><a href="#3-配置全局异常拦截的类" class="headerlink" title="3. 配置全局异常拦截的类"></a>3. 配置全局异常拦截的类</h3><p><code>GlobalException.java</code></p>
<div class="code-wrapper"><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">package</span> <span class="token namespace">com<span class="token punctuation">.</span>codehope<span class="token punctuation">.</span>ch<span class="token punctuation">.</span>core</span><span class="token punctuation">;</span>

<span class="token keyword">import</span> <span class="token namespace">com<span class="token punctuation">.</span>codehope<span class="token punctuation">.</span>ch<span class="token punctuation">.</span>exception<span class="token punctuation">.</span></span><span class="token class-name">HttpException</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">com<span class="token punctuation">.</span>codehope<span class="token punctuation">.</span>ch<span class="token punctuation">.</span>exception<span class="token punctuation">.</span></span><span class="token class-name">NotFoundException</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>beans<span class="token punctuation">.</span>factory<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span></span><span class="token class-name">Autowired</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>web<span class="token punctuation">.</span>bind<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span></span><span class="token class-name">ControllerAdvice</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>web<span class="token punctuation">.</span>bind<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span></span><span class="token class-name">ExceptionHandler</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>web<span class="token punctuation">.</span>bind<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span></span><span class="token class-name">RestController</span><span class="token punctuation">;</span>

<span class="token keyword">import</span> <span class="token namespace">javax<span class="token punctuation">.</span>servlet<span class="token punctuation">.</span>http<span class="token punctuation">.</span></span><span class="token class-name">HttpServletRequest</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">javax<span class="token punctuation">.</span>servlet<span class="token punctuation">.</span>http<span class="token punctuation">.</span></span><span class="token class-name">HttpServletResponse</span><span class="token punctuation">;</span>

<span class="token annotation punctuation">@ControllerAdvice</span>
<span class="token annotation punctuation">@RestController</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">GlobalException</span> <span class="token punctuation">&#123;</span>

    <span class="token keyword">private</span> <span class="token class-name">String</span> message<span class="token punctuation">;</span>

    <span class="token keyword">public</span> <span class="token class-name">UnifyResponse</span> unifyResponse<span class="token punctuation">;</span>

    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setUnifyResponse</span><span class="token punctuation">(</span><span class="token class-name">UnifyResponse</span> unifyResponse<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>unifyResponse <span class="token operator">=</span> unifyResponse<span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>

    <span class="token annotation punctuation">@ExceptionHandler</span><span class="token punctuation">(</span>value <span class="token operator">=</span> <span class="token class-name">Exception</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span>
    <span class="token comment">//处理未知异常</span>
    <span class="token keyword">public</span> <span class="token class-name">UnifyResponse</span> <span class="token class-name">UnKnownException</span><span class="token punctuation">(</span><span class="token class-name">HttpServletRequest</span> request<span class="token punctuation">,</span> <span class="token class-name">HttpServletResponse</span> response<span class="token punctuation">,</span> <span class="token class-name">Exception</span> e<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token comment">//未知异常的一些返回的状态码可以是写死的</span>
        message <span class="token operator">=</span> <span class="token string">"系统发生了未知异常~o(╥﹏╥)o"</span><span class="token punctuation">;</span>
        unifyResponse<span class="token punctuation">.</span><span class="token function">setCode</span><span class="token punctuation">(</span><span class="token number">999</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        unifyResponse<span class="token punctuation">.</span><span class="token function">setMessage</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span>
        unifyResponse<span class="token punctuation">.</span><span class="token function">setUrl</span><span class="token punctuation">(</span><span class="token string">"/test"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> unifyResponse<span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>

    <span class="token annotation punctuation">@ExceptionHandler</span><span class="token punctuation">(</span>value <span class="token operator">=</span> <span class="token class-name">NotFoundException</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> <span class="token class-name">UnifyResponse</span> <span class="token class-name">NotFoundException</span><span class="token punctuation">(</span><span class="token class-name">HttpServletRequest</span> request<span class="token punctuation">,</span> <span class="token class-name">HttpServletResponse</span> response<span class="token punctuation">,</span> <span class="token class-name">HttpException</span> httpException<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        message <span class="token operator">=</span> <span class="token string">"资源未找到！"</span><span class="token punctuation">;</span>
        <span class="token class-name">String</span> url <span class="token operator">=</span> request<span class="token punctuation">.</span><span class="token function">getRequestURI</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">String</span> method <span class="token operator">=</span> request<span class="token punctuation">.</span><span class="token function">getMethod</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        unifyResponse<span class="token punctuation">.</span><span class="token function">setCode</span><span class="token punctuation">(</span>httpException<span class="token punctuation">.</span>code<span class="token punctuation">)</span><span class="token punctuation">;</span>
        unifyResponse<span class="token punctuation">.</span><span class="token function">setMessage</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span>
        unifyResponse<span class="token punctuation">.</span><span class="token function">setUrl</span><span class="token punctuation">(</span>method <span class="token operator">+</span> <span class="token string">" "</span> <span class="token operator">+</span> url<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> unifyResponse<span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></div>
<h3 id="4-分析全局异常的类"><a href="#4-分析全局异常的类" class="headerlink" title="4.分析全局异常的类"></a>4.分析全局异常的类</h3><p><img src="http://qiniuyun.quancundexiwang.wang/image-20210430182913521.png" srcset="/img/loading.gif" alt="image-20210430182913521"></p>
<ol>
<li><p>这里给这个全局异常拦截的类加<code>@RestController</code>的原因：你可以理解为这个类是拦截了控制器<code>controller</code>错误，</p>
<p>而<code>controller</code>,将这个错误转发给了<code>@ControllerAdvice</code>标记的类！</p>
<p>所以，如果某个控制器出了问题，转发到你这里，那么返回前端相关的数据，也是由这个类的某个方法去做，所以你可以拿到请求对象和响应对象！也可以对前端进行数据的返回！</p>
</li>
<li><p>注入<code>UnfiyResponse</code>这个Bean,是为了生成对应的错误格式对象！然后序列化后，经由某个错误处理的方法把这个收集错误信息的对象返回出去</p>
</li>
</ol>
<p><img src="http://qiniuyun.quancundexiwang.wang/image-20210430183655584.png" srcset="/img/loading.gif" alt="image-20210430183655584"></p>
<ol>
<li>1和3都是指定了当前异常处理器需要处理的异常类型，根据不同的异常类型全局的配置类会调用不同的异常处理器方法！因为自定义的<code>XxxxException</code>都是继承自Java为我们提供的<code>Exception</code>,所以如果有自定义的异常抛出优先去匹配自定义的<code>Exception</code>，如果没有的话，那就去匹配<code>Java</code>提供的 <code>Exception</code></li>
<li>2和4都表示为注入的<code>UnfiyResponse</code>设置错误的信息，然后准备返回出去！</li>
</ol>
<h3 id="5-测试一下Test"><a href="#5-测试一下Test" class="headerlink" title="5.测试一下Test"></a>5.测试一下Test</h3><p><img src="http://qiniuyun.quancundexiwang.wang/image-20210430184635149.png" srcset="/img/loading.gif" alt="image-20210430184635149"></p>
<p>发现的确是成功的返回了我们需要的规范的格式！但是不知道你有没有发现一个细节，那就是状态码依旧返回的是 200，感觉像个假的返回！哈哈哈</p>
<p>那么就可以使用一个新的注解，<code>@ResponseStatus</code>,可以设置响应的<code>http</code>状态码,传入的是一个枚举的类型</p>
<p><img src="http://qiniuyun.quancundexiwang.wang/image-20210430185125753.png" srcset="/img/loading.gif" alt="image-20210430185125753"></p>
<p>然后给我们对应的异常拦截器加上对应的<code>@ResponseStatus</code></p>
<p><img src="http://qiniuyun.quancundexiwang.wang/image-20210430185314399.png" srcset="/img/loading.gif" alt="image-20210430185314399"></p>
<p>再试一下</p>
<p><img src="http://qiniuyun.quancundexiwang.wang/image-20210430185334866.png" srcset="/img/loading.gif" alt="image-20210430185334866"></p>
<p>那么就OK啦！</p>
<h2 id="6-优化我们的错误拦截"><a href="#6-优化我们的错误拦截" class="headerlink" title="6.优化我们的错误拦截"></a>6.优化我们的错误拦截</h2><h3 id="1-优化code和message"><a href="#1-优化code和message" class="headerlink" title="1. 优化code和message"></a>1. 优化code和message</h3><p>首先我们不希望把message写进代码中！因为如果有国际化的需求，我们希望能通过替换配置文件的形式完成！而不是逐个去更改代码中的文字！</p>
<p><code>exception-code.properties</code></p>
<div class="code-wrapper"><pre class="line-numbers language-properties" data-language="properties"><code class="language-properties"><span class="token comment"># 参数异常</span>
<span class="token attr-name">hope.codes[10001]</span><span class="token punctuation">=</span><span class="token attr-value">参数错误</span>
<span class="token attr-name">hope.codes[10002]</span><span class="token punctuation">=</span><span class="token attr-value">参数不全</span>
<span class="token attr-name">hope.codes[10003]</span><span class="token punctuation">=</span><span class="token attr-value">参数类型错误</span>
<span class="token attr-name">hope.codes[10004]</span><span class="token punctuation">=</span><span class="token attr-value">参数无效</span>

<span class="token comment"># 用户异常</span>
<span class="token attr-name">hope.codes[20001]</span><span class="token punctuation">=</span><span class="token attr-value">用户不存在</span>
<span class="token attr-name">hope.codes[20002]</span><span class="token punctuation">=</span><span class="token attr-value">用户未登陆</span>
<span class="token attr-name">hope.codes[20003]</span><span class="token punctuation">=</span><span class="token attr-value">用户名或密码错误</span>
<span class="token attr-name">hope.codes[20004]</span><span class="token punctuation">=</span><span class="token attr-value">用户账户已被禁用</span>
<span class="token attr-name">hope.codes[20005]</span><span class="token punctuation">=</span><span class="token attr-value">用户已存在</span>

<span class="token comment"># 业务异常</span>
<span class="token attr-name">hope.codes[30001]</span><span class="token punctuation">=</span><span class="token attr-value">系统业务出现问题</span>
<span class="token attr-name">hope.codes[40001]</span><span class="token punctuation">=</span><span class="token attr-value">系统内部错误</span>

<span class="token comment"># 数据异常</span>
<span class="token attr-name">hope.codes[50001]</span><span class="token punctuation">=</span><span class="token attr-value">数据未找到</span>
<span class="token attr-name">hope.codes[50002]</span><span class="token punctuation">=</span><span class="token attr-value">数据有误</span>
<span class="token attr-name">hope.codes[50003]</span><span class="token punctuation">=</span><span class="token attr-value">数据已存在</span>

<span class="token comment"># 接口异常</span>
<span class="token attr-name">hope.codes[60003]</span><span class="token punctuation">=</span><span class="token attr-value">没有访问权限</span>
<span class="token attr-name">hope.codes[70001]</span><span class="token punctuation">=</span><span class="token attr-value">接口禁止访问</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></div>
<p>根据配置文件创建对应的配置类！</p>
<p><code>ExceptionCode.java</code></p>
<div class="code-wrapper"><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">package</span> <span class="token namespace">com<span class="token punctuation">.</span>codehope<span class="token punctuation">.</span>ch<span class="token punctuation">.</span>core</span><span class="token punctuation">;</span>

<span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>boot<span class="token punctuation">.</span>context<span class="token punctuation">.</span>properties<span class="token punctuation">.</span></span><span class="token class-name">ConfigurationProperties</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>context<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span></span><span class="token class-name">PropertySource</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>stereotype<span class="token punctuation">.</span></span><span class="token class-name">Component</span><span class="token punctuation">;</span>

<span class="token keyword">import</span> <span class="token namespace">java<span class="token punctuation">.</span>util<span class="token punctuation">.</span></span><span class="token class-name">Map</span><span class="token punctuation">;</span>

<span class="token annotation punctuation">@PropertySource</span><span class="token punctuation">(</span>value <span class="token operator">=</span> <span class="token string">"classpath:config/exception-code.properties"</span><span class="token punctuation">,</span> encoding <span class="token operator">=</span> <span class="token string">"utf-8"</span><span class="token punctuation">)</span>
<span class="token annotation punctuation">@ConfigurationProperties</span><span class="token punctuation">(</span>prefix <span class="token operator">=</span> <span class="token string">"hope"</span><span class="token punctuation">)</span>
<span class="token annotation punctuation">@Component</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">ExceptionCode</span> <span class="token punctuation">&#123;</span>
    <span class="token keyword">private</span> <span class="token class-name">Map</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">Integer</span><span class="token punctuation">,</span> <span class="token class-name">String</span><span class="token punctuation">></span></span> codes<span class="token punctuation">;</span>

    <span class="token keyword">public</span> <span class="token class-name">Map</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">Integer</span><span class="token punctuation">,</span> <span class="token class-name">String</span><span class="token punctuation">></span></span> <span class="token function">getCodes</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token keyword">return</span> codes<span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>

    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setCodes</span><span class="token punctuation">(</span><span class="token class-name">Map</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">Integer</span><span class="token punctuation">,</span> <span class="token class-name">String</span><span class="token punctuation">></span></span> codes<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>codes <span class="token operator">=</span> codes<span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>

    <span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">getMessageByCode</span><span class="token punctuation">(</span><span class="token class-name">Integer</span> code<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token keyword">return</span> codes<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>code<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>

    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token keyword">return</span> <span class="token string">"ExceptionCode&#123;"</span> <span class="token operator">+</span>
                <span class="token string">"codes="</span> <span class="token operator">+</span> codes <span class="token operator">+</span>
                <span class="token string">'&#125;'</span><span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></div>
<ul>
<li><code>@PropertySource(value = &quot;classpath:config/exception-code.properties&quot;, encoding = &quot;utf-8&quot;)</code> 指定配置文件的class路径</li>
<li><code>@ConfigurationProperties(prefix = &quot;hope&quot;)</code> 代表配置文件中前缀字段的配置</li>
<li><code>@Component</code> 注入容器</li>
</ul>
<p><img src="http://qiniuyun.quancundexiwang.wang/image-20210501125621075.png" srcset="/img/loading.gif" alt="image-20210501125621075"></p>
<ol>
<li>根据配置文件key-value的形式匹配<code>java</code>中的<code>Map</code>集合,并且需要提供<code>get/set</code>方法，才能将配置文件的值注入map</li>
<li>从map中根据code拿去message</li>
</ol>
<h3 id="2-优化全局异常拦截类的拦截器！"><a href="#2-优化全局异常拦截类的拦截器！" class="headerlink" title="2. 优化全局异常拦截类的拦截器！"></a>2. 优化全局异常拦截类的拦截器！</h3><p><img src="http://qiniuyun.quancundexiwang.wang/image-20210501130230054.png" srcset="/img/loading.gif" alt="image-20210501130230054"></p>
<p>上面我们根据每一种不同自定义异常！都写了一个对应异常处理器，但是其实完全不用每个都去写的，这样比较麻烦！因为每种信息都可以通过<code>HttpException</code>的实例获得，就可以自动根据不同的异常返回前端对应异常信息！</p>
<p><code>HttpException.java</code></p>
<div class="code-wrapper"><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">package</span> <span class="token namespace">com<span class="token punctuation">.</span>codehope<span class="token punctuation">.</span>ch<span class="token punctuation">.</span>exception</span><span class="token punctuation">;</span>

<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">HttpException</span> <span class="token keyword">extends</span> <span class="token class-name">Exception</span> <span class="token punctuation">&#123;</span>
    <span class="token comment">//自定义的code</span>
    <span class="token keyword">public</span> <span class="token class-name">Integer</span> code<span class="token punctuation">;</span>
    <span class="token comment">//http状态码</span>
    <span class="token keyword">public</span> <span class="token class-name">Integer</span> <span class="token class-name">HttpStatus</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></div>
<p>自定义两个异常类！状态写死在内部，根据code可以匹配不同的message！可以让我们的状态更丰富健壮！</p>
<p><img src="http://qiniuyun.quancundexiwang.wang/image-20210501130548765.png" srcset="/img/loading.gif"></p>
<p>然后是我们的全局的配置类中的<code>HttpException</code>拦截器</p>
<div class="code-wrapper"><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">package</span> <span class="token namespace">com<span class="token punctuation">.</span>codehope<span class="token punctuation">.</span>ch<span class="token punctuation">.</span>core</span><span class="token punctuation">;</span>

<span class="token keyword">import</span> <span class="token namespace">com<span class="token punctuation">.</span>codehope<span class="token punctuation">.</span>ch<span class="token punctuation">.</span>exception<span class="token punctuation">.</span></span><span class="token class-name">HttpException</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">com<span class="token punctuation">.</span>codehope<span class="token punctuation">.</span>ch<span class="token punctuation">.</span>exception<span class="token punctuation">.</span></span><span class="token class-name">NotFoundException</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>beans<span class="token punctuation">.</span>factory<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span></span><span class="token class-name">Autowired</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>http<span class="token punctuation">.</span></span><span class="token class-name">HttpStatus</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>web<span class="token punctuation">.</span>bind<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span></span><span class="token class-name">ControllerAdvice</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>web<span class="token punctuation">.</span>bind<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span></span><span class="token class-name">ExceptionHandler</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>web<span class="token punctuation">.</span>bind<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span></span><span class="token class-name">ResponseStatus</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>web<span class="token punctuation">.</span>bind<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span></span><span class="token class-name">RestController</span><span class="token punctuation">;</span>

<span class="token keyword">import</span> <span class="token namespace">javax<span class="token punctuation">.</span>servlet<span class="token punctuation">.</span>http<span class="token punctuation">.</span></span><span class="token class-name">HttpServletRequest</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">javax<span class="token punctuation">.</span>servlet<span class="token punctuation">.</span>http<span class="token punctuation">.</span></span><span class="token class-name">HttpServletResponse</span><span class="token punctuation">;</span>

<span class="token annotation punctuation">@ControllerAdvice</span>
<span class="token annotation punctuation">@RestController</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">GlobalException</span> <span class="token punctuation">&#123;</span>
    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">private</span> <span class="token class-name">ExceptionCode</span> exceptionCode<span class="token punctuation">;</span>

    <span class="token keyword">public</span> <span class="token class-name">UnifyResponse</span> unifyResponse<span class="token punctuation">;</span>

    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setUnifyResponse</span><span class="token punctuation">(</span><span class="token class-name">UnifyResponse</span> unifyResponse<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>unifyResponse <span class="token operator">=</span> unifyResponse<span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>

    <span class="token annotation punctuation">@ExceptionHandler</span><span class="token punctuation">(</span>value <span class="token operator">=</span> <span class="token class-name">Exception</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span>
    <span class="token comment">//处理未知异常</span>
    <span class="token keyword">public</span> <span class="token class-name">UnifyResponse</span> <span class="token class-name">UnKnownException</span><span class="token punctuation">(</span><span class="token class-name">HttpServletRequest</span> request<span class="token punctuation">,</span> <span class="token class-name">HttpServletResponse</span> response<span class="token punctuation">,</span> <span class="token class-name">Exception</span> e<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token comment">//未知异常的一些返回的状态码可以是写死的</span>
        <span class="token class-name">String</span> message <span class="token operator">=</span> <span class="token string">"系统发生了未知异常~o(╥﹏╥)o"</span><span class="token punctuation">;</span>
        unifyResponse<span class="token punctuation">.</span><span class="token function">setCode</span><span class="token punctuation">(</span><span class="token number">99999</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        unifyResponse<span class="token punctuation">.</span><span class="token function">setMessage</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span>
        unifyResponse<span class="token punctuation">.</span><span class="token function">setUrl</span><span class="token punctuation">(</span><span class="token string">"/test"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> unifyResponse<span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>

    <span class="token annotation punctuation">@ExceptionHandler</span><span class="token punctuation">(</span>value <span class="token operator">=</span> <span class="token class-name">HttpException</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> <span class="token class-name">UnifyResponse</span> <span class="token function">httpException</span><span class="token punctuation">(</span><span class="token class-name">HttpServletRequest</span> request<span class="token punctuation">,</span> <span class="token class-name">HttpServletResponse</span> response<span class="token punctuation">,</span> <span class="token class-name">HttpException</span> httpException<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token comment">//通过配置文件生成异常配置类！根据匹配code拿到message</span>
        <span class="token class-name">String</span> message <span class="token operator">=</span> exceptionCode<span class="token punctuation">.</span><span class="token function">getMessageByCode</span><span class="token punctuation">(</span>httpException<span class="token punctuation">.</span>code<span class="token punctuation">)</span><span class="token punctuation">;</span>

        <span class="token comment">//根据请求对象，拿到请求的URI和method</span>
        <span class="token class-name">String</span> url <span class="token operator">=</span> request<span class="token punctuation">.</span><span class="token function">getRequestURI</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">String</span> method <span class="token operator">=</span> request<span class="token punctuation">.</span><span class="token function">getMethod</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

        <span class="token comment">//通过响应对象设置不同异常类对应的http状态码，响应给前端</span>
        response<span class="token punctuation">.</span><span class="token function">setStatus</span><span class="token punctuation">(</span><span class="token class-name"><span class="token namespace">httpException<span class="token punctuation">.</span></span>HttpStatus</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

        <span class="token comment">//设置bean处理的返回信息</span>
        unifyResponse<span class="token punctuation">.</span><span class="token function">setCode</span><span class="token punctuation">(</span>httpException<span class="token punctuation">.</span>code<span class="token punctuation">)</span><span class="token punctuation">;</span>
        unifyResponse<span class="token punctuation">.</span><span class="token function">setMessage</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span>
        unifyResponse<span class="token punctuation">.</span><span class="token function">setUrl</span><span class="token punctuation">(</span>method <span class="token operator">+</span> <span class="token string">" "</span> <span class="token operator">+</span> url<span class="token punctuation">)</span><span class="token punctuation">;</span>

        <span class="token keyword">return</span> unifyResponse<span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></div>


<p><img src="http://qiniuyun.quancundexiwang.wang/image-20210501130847108.png" srcset="/img/loading.gif" alt="image-20210501130847108"></p>
<p>那么我们就先测试一下当前优化的结果！</p>
<p><img src="http://qiniuyun.quancundexiwang.wang/image-20210501131130484.png" srcset="/img/loading.gif" alt="image-20210501131130484"></p>
<p><img src="http://qiniuyun.quancundexiwang.wang/image-20210501131257681.png" srcset="/img/loading.gif" alt="image-20210501131257681"></p>

            </div>
            <hr>
            <div>
              <div class="post-metas mb-3">
                
                  <div class="post-meta mr-3">
                    <i class="iconfont icon-category"></i>
                    
                      <a class="hover-with-bg" href="/categories/Java/">Java</a>
                    
                  </div>
                
                
                  <div class="post-meta">
                    <i class="iconfont icon-tags"></i>
                    
                      <a class="hover-with-bg" href="/tags/SpringBoot%E5%9F%BA%E7%A1%80/">SpringBoot基础</a>
                    
                  </div>
                
              </div>
              
                <p class="note note-warning">本博客所有文章除特别声明外，均采用 <a target="_blank" href="https://creativecommons.org/licenses/by-sa/4.0/deed.zh" rel="nofollow noopener noopener">CC BY-SA 4.0 协议</a> ，转载请注明出处！</p>
              
              
                <div class="post-prevnext">
                  <article class="post-prev col-6">
                    
                    
                      <a href="/posts/22266/">
                        <i class="iconfont icon-arrowleft"></i>
                        <span class="hidden-mobile">SpringBoot控制器自动根据所在目录配置prefix</span>
                        <span class="visible-mobile">上一篇</span>
                      </a>
                    
                  </article>
                  <article class="post-next col-6">
                    
                    
                      <a href="/posts/54526/">
                        <span class="hidden-mobile">SpringBoot框架的入门</span>
                        <span class="visible-mobile">下一篇</span>
                        <i class="iconfont icon-arrowright"></i>
                      </a>
                    
                  </article>
                </div>
              
            </div>

            
              <!-- Comments -->
              <article class="comments" id="comments">
                
                
  <div id="vcomments"></div>
  <script type="text/javascript">
    Fluid.utils.waitElementVisible('vcomments', function() {
      Fluid.utils.createScript('https://cdn.jsdelivr.net/npm/valine@1.4.14/dist/Valine.min.js', function () {
        new Valine({
          el: "#vcomments",
          app_id: "Mi65hxq7VAFUDwOLeIGAOgiV-gzGzoHsz",
          app_key: "hMuhiD4FRqhns4giqLiEH9HG",
          placeholder: "说点什么",
          path: window.location.pathname,
          avatar: "retro",
          meta: ["nick","mail","link"],
          pageSize: "10",
          lang: "zh-CN",
          highlight: false,
          recordIP: false,
          serverURLs: "",
        });
      });
    });
  </script>
  <noscript>Please enable JavaScript to view the
    <a target="_blank" href="https://valine.js.org" rel="nofollow noopener noopener">comments powered by Valine.</a>
  </noscript>


              </article>
            
          </article>
        </div>
      </div>
    </div>
    
      <div class="d-none d-lg-block col-lg-2 toc-container" id="toc-ctn">
        <div id="toc">
  <p class="toc-header"><i class="iconfont icon-list"></i>&nbsp;目录</p>
  <div class="toc-body" id="toc-body"></div>
</div>

      </div>
    
  </div>
</div>

<!-- Custom -->


    

    
      <a id="scroll-top-button" href="#" role="button">
        <i class="iconfont icon-arrowup" aria-hidden="true"></i>
      </a>
    

    
      <div class="modal fade" id="modalSearch" tabindex="-1" role="dialog" aria-labelledby="ModalLabel"
     aria-hidden="true">
  <div class="modal-dialog modal-dialog-scrollable modal-lg" role="document">
    <div class="modal-content">
      <div class="modal-header text-center">
        <h4 class="modal-title w-100 font-weight-bold">搜索</h4>
        <button type="button" id="local-search-close" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body mx-3">
        <div class="md-form mb-5">
          <input type="text" id="local-search-input" class="form-control validate">
          <label data-error="x" data-success="v"
                 for="local-search-input">关键词</label>
        </div>
        <div class="list-group" id="local-search-result"></div>
      </div>
    </div>
  </div>
</div>
    

    
  </main>

  <footer class="text-center mt-5 py-3">
  <div class="footer-content">
    

  </div>
  
  <div class="statistics">
    
    

    
      
        <!-- 不蒜子统计PV -->
        <span id="busuanzi_container_site_pv" style="display: none">
            总访问量 
            <span id="busuanzi_value_site_pv"></span>
             次
          </span>
      
      
        <!-- 不蒜子统计UV -->
        <span id="busuanzi_container_site_uv" style="display: none">
            总访客数 
            <span id="busuanzi_value_site_uv"></span>
             人
          </span>
      
    
  </div>


  
  <!-- 备案信息 -->
  <div class="beian">
    <span>
      <a href="http://beian.miit.gov.cn/" target="_blank" rel="nofollow noopener">
        豫ICP备20009912号-1
      </a>
    </span>
    
  </div>


  
</footer>

<!-- SCRIPTS -->

  <script  src="https://cdn.jsdelivr.net/npm/nprogress@0.2.0/nprogress.min.js" ></script>
  <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/nprogress@0.2.0/nprogress.min.css" />

  <script>
    NProgress.configure({"showSpinner":true,"trickleSpeed":100})
    NProgress.start()
    window.addEventListener('load', function() {
      NProgress.done();
    })
  </script>


<script  src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js" ></script>
<script  src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.min.js" ></script>
<script  src="/js/debouncer.js" ></script>
<script  src="/js/events.js" ></script>
<script  src="/js/plugins.js" ></script>

<!-- Plugins -->


  
    
      <script  src="/js/lazyload.js" ></script>
    
  



  
    
  



  <script  src="https://cdn.jsdelivr.net/npm/tocbot@4.12.0/dist/tocbot.min.js" ></script>



  <script  src="https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.js" ></script>



  <script  src="https://cdn.jsdelivr.net/npm/anchor-js@4.3.0/anchor.min.js" ></script>



  <script defer src="https://cdn.jsdelivr.net/npm/clipboard@2.0.6/dist/clipboard.min.js" ></script>



  <script defer src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js" ></script>




  <script  src="https://cdn.jsdelivr.net/npm/typed.js@2.0.11/lib/typed.min.js" ></script>
  <script>
    (function (window, document) {
      var typing = Fluid.plugins.typing;
      var title = document.getElementById('subtitle').title;
      
      typing(title)
      
    })(window, document);
  </script>



  <script  src="/js/local-search.js" ></script>
  <script>
    (function () {
      var path = "http://qiniuyun.quancundexiwang.wang/xmlSearch.xml";
      var inputArea = document.querySelector("#local-search-input");
      inputArea.onclick = function () {
        searchFunc(path, 'local-search-input', 'local-search-result');
        this.onclick = null
      }
    })()
  </script>















<!-- 主题的启动项 保持在最底部 -->
<script  src="/js/boot.js" ></script>



</body>
</html>
